home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Merciful 2
/
Merciful - Disc 2.iso
/
software
/
d
/
dialupv3.06.lha
/
dialup
/
io.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-30
|
11KB
|
459 lines
#include "dialup.h"
extern const UBYTE *prgname;
extern struct IOExtSer *serialIOReq;
extern struct timerequest *timereq;
extern BPTR repfile;
extern UBYTE *rxbuffer;
extern LONG arg[];
BOOL isend( UBYTE *send ); /* real send with \r, \n and \t remapping, string must be in a bigger buffer */
UBYTE *
expectFromSer( UBYTE *expect, USHORT waittime )
{
UBYTE *result = NULL;
ULONG WaitMask, timebit, serbit, wres;
WaitMask = 0;
if ( waittime )
{
if ( arg[A_VERBOSE] && !expect )
msg("waiting %ld seconds\n", expect, waittime);
timebit = 1L << timereq->tr_node.io_Message.mn_ReplyPort->mp_SigBit;
SetSignal(0L, timebit);
WaitMask |= SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | timebit;
timereq->tr_node.io_Command = TR_ADDREQUEST;
timereq->tr_time.tv_secs = waittime;
timereq->tr_time.tv_micro = 0;
SendIO((struct IORequest *)timereq);
if ( !expect )
{
while ( ! ( (wres = Wait(WaitMask)) & WaitMask ) )
; /* Wait for the timeout, no string expected! */
if ( wres & timebit )
{
*rxbuffer = '\0';
result = rxbuffer;
};
};
};
if ( expect )
{
UBYTE *wptrb;
UBYTE *repptr;
UBYTE mbuf[MAXMATCHSTRING * 25];
UBYTE *msa[MAXMATCHSTRING];
if ( strlen(expect) > sizeof(mbuf) )
{
msg("expectFromSer: expectstring to long!");
_FAIL_;
};
if ( arg[A_VERBOSE] )
msg("expecting %s for %ld seconds\n", expect, waittime);
buildMatchStringArray(expect, mbuf, msa);
serbit = 1L << serialIOReq->IOSer.io_Message.mn_ReplyPort->mp_SigBit;
SetSignal(0L, serbit);
WaitMask |= SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | serbit;
wptrb = repptr = rxbuffer;
wres = 0;
do
{
UBYTE *spt;
serialIOReq->IOSer.io_Command = SDCMD_QUERY;
DoIO((struct IORequest *)serialIOReq);
serialIOReq->IOSer.io_Command = CMD_READ;
serialIOReq->IOSer.io_Data = (APTR)wptrb;
/* while there are chars on the serial, set and get them (upto bufsize): */
if ( ( serialIOReq->IOSer.io_Length = min(serialIOReq->IOSer.io_Actual, RXBUFSIZE - (wptrb - rxbuffer)) ) > 0 )
{
DoIO((struct IORequest *)serialIOReq);
wptrb += serialIOReq->IOSer.io_Actual;
continue;
}
*wptrb = '\0'; /* Terminate received string and replace any received \0's with spaces, to make a stringsearch possible: */
while ( spt = memchr(repptr, '\0', wptrb - repptr ) )
memmove(spt, spt + 1, wptrb-- - spt);
/* Report the conversation. The modem echos commands sent to it: */
if ( repfile && wptrb > repptr )
{
Write( repfile, repptr, wptrb - repptr);
repptr = wptrb;
};
/* check whether one of the matchstrings is in the receive buffer. Stop and return it if so. */
if ( result = matchString(rxbuffer, msa) )
break;
/* wait for one char, break or timeout: */
serialIOReq->IOSer.io_Length = 1;
SetSignal(0L, serbit);
SendIO((struct IORequest *)serialIOReq);
while ( ! ( (wres = Wait(WaitMask)) & WaitMask ) )
;
if ( wres & serbit || wres & SIGBREAKF_CTRL_F )
{
if(CheckIO((struct IORequest *)serialIOReq) ) /* If request is complete... */
{
WaitIO((struct IORequest *)serialIOReq); /* clean up and remove reply */
wptrb += serialIOReq->IOSer.io_Actual;
*wptrb = '\0'; /* Terminate received string */
}
}
else if ( (wres & timebit) )
{
UBYTE *cbptr;
UBYTE *rbptr;
UBYTE ccnt;
for(rbptr = rxbuffer, cbptr = wptrb + 1; ( rbptr < wptrb ) && ((cbptr + 20) < (rxbuffer + RXBUFSIZE)); rbptr += 8)
{
cbptr += sprintf(cbptr, "%08lX %08lX ", *(ULONG *)rbptr, *(ULONG *)(rbptr + 4) );
for(ccnt = 0; rbptr[ccnt] && ccnt < 8; ccnt++)
if ( strchr("\n\r\t", rbptr[ccnt] ) )
rbptr[ccnt] = 1;
cbptr += sprintf(cbptr, "%-.4s ", rbptr);
if (rbptr + 4 < wptrb)
cbptr += sprintf(cbptr, "%-.4s\n", rbptr + 4 );
};
msg("TIMEOUT, after waiting %ld secs for:\n'%s'\nReceived:\n%s", waittime, expect, wptrb + 1);
}
}
while ( ! ( wres & ( SIGBREAKF_CTRL_C | timebit ) ) )
;
if ( wres & SIGBREAKF_CTRL_C )
{
strcpy(wptrb, BREAKSTR);
wptrb += sizeof(BREAKSTR);
};
if( !CheckIO((struct IORequest *)serialIOReq) ) /* If request is complete... */
{
AbortIO((struct IORequest *)serialIOReq); /* Ask device to abort request, if pending */
WaitIO((struct IORequest *)serialIOReq); /* clean up and remove reply */
if ( SetSignal(0, 0) & serbit )
SetSignal(0, serbit );
}
if ( repfile && (wptrb > repptr) )
{
Write( repfile, repptr, wptrb - repptr); /* Report the conversation, cause normaly modem echos commands sent to it. */
repptr = wptrb;
};
};
if( waittime && !CheckIO((struct IORequest *)timereq) ) /* Abort any pending timer requests */
{
AbortIO((struct IORequest *)timereq);
WaitIO((struct IORequest *)timereq);
if ( SetSignal(0, 0) & timebit )
SetSignal(0, timebit );
}
return( result );
}
#define SCRATCHBUFSIZE 1000
BOOL
sendLine( UBYTE *send )
{
UBYTE buf[SCRATCHBUFSIZE];
if ( strlen(send) >= SCRATCHBUFSIZE - 1 )
_FAIL_
sprintf(buf, "%s\r", send);
return(isend(buf));
}
UBYTE *
sendEx( UBYTE *send , UBYTE *expect, USHORT waittime )
{
UBYTE buf[SCRATCHBUFSIZE];
if ( strlen(send) >= SCRATCHBUFSIZE - 1 )
_FAIL_
sprintf(buf, "%s\r", send);
if ( !isend(buf) )
return(FALSE);
return( expectFromSer(expect, waittime) );
}
UBYTE *
exSend( UBYTE *expect, USHORT waittime, UBYTE *send )
{
UBYTE *rxbufp;
if ( strlen(send) >= SCRATCHBUFSIZE - 1 )
_FAIL_
if (rxbufp = expectFromSer(expect, waittime) )
{
UBYTE buf[SCRATCHBUFSIZE];
sprintf(buf, "%s\r", send);
if ( !isend(buf) )
return(NULL);
}
return(rxbufp);
}
BOOL
sendToSer( UBYTE *send )
{
UBYTE buf[SCRATCHBUFSIZE];
if ( strlen(send) >= SCRATCHBUFSIZE )
_FAIL_
strcpy(buf, send); /* copying string to be able modify it */
return(isend(send));
}
BOOL
isend( UBYTE *send ) /* this gets only called by sendEx(), exSend() and sendToSer() */
{
UBYTE *mptr = send;
while ( *mptr != '\0' )
{
if ( *mptr++ == '\\' )
{
if ( *mptr == 'r' )
*mptr = '\r'; /* overwrite it insitu */
else if ( *mptr == 'n' )
*mptr = '\n'; /* ditto */
else if ( *mptr == 't' )
*mptr = '\t'; /* ditto */
/* then get rid of the '\\' by left shifting the string */
memmove(mptr - 1, mptr, strlen(mptr) + 1);
};
};
if ( arg[A_VERBOSE] )
msg("Sending %s\n", send);
Delay(2);
serialIOReq->IOSer.io_Command = CMD_WRITE;
serialIOReq->IOSer.io_Data = (APTR)send;
serialIOReq->IOSer.io_Length = strlen(send);
if ( DoIO( (struct IORequest *)serialIOReq ) )
{
msg("failed to write to serial line\n");
return(FALSE);
}
return(TRUE);
}
/* new function to handle WAKEUPSTRING -GH- */
BOOL
sendWUSSer( UBYTE *send )
{
UBYTE buf[SCRATCHBUFSIZE];
if ( strlen(send) >= SCRATCHBUFSIZE )
_FAIL_
strcpy(buf, send); /* copying string to be able modify it */
return(wuSend(send));
}
BOOL
wuSend( UBYTE *send ) /* this gets only called by sendWUSSer() -GH- */
{
UBYTE *mptr = send;
UBYTE kick;
while ( *mptr != '\0' )
{
if ( *mptr++ == '\\' )
{ /* added to implement a delay mechanism by Gene Heskett */
if ( *mptr == '*' )
Delay(15); /* 1/4 second delay */
else if ( *mptr == 'r' )
{
kick = '\r';
kickport (& kick );
}
else if ( *mptr == 'n' )
{
kick = '\n';
kickport ( & kick );
}
else if ( *mptr == 't' )
{
kick = '\t';
kickport ( & kick );
}
memmove(mptr - 1, mptr, strlen(mptr) + 1);
};
};
return TRUE;
} /* this is the new end of this routine -GH- */
BOOL
kickport ( UBYTE *send ) /* called *only* by wuSend */
{
if ( arg[A_VERBOSE] )
msg("Sending %s\n", send);
serialIOReq->IOSer.io_Command = CMD_WRITE;
serialIOReq->IOSer.io_Data = (APTR)send;
serialIOReq->IOSer.io_Length = 1;
if ( DoIO( (struct IORequest *)serialIOReq ) )
{
msg("failed to write to serial line\n");
return(FALSE);
}
return(TRUE);
}
/*
** The next lines are stolen from the slip.device (Rhialto Seibert, Comodore)
**
** ReadConfig
**
** Attempt to read in and parse the driver's configuration file.
**
** The files are named by ENV:SANA2/slip0.config where X is the decimal
** representation of the device's unit number.
**
*/
#define LINEBUFFSIZE 1024
#define NUMARGS 10
BOOL ReadConfig(STRPTR sanacfgfile, USHORT sanaUnit, struct SP *sp)
{
UBYTE *linebuff;
UBYTE buff[80] = "ENV:SANA2/";
UBYTE *termchar;
struct RDArgs *rdargs;
BPTR ConfigFile;
LONG arg[NUMARGS];
BOOL status = FALSE;
ULONG linenum=0;
UWORD i;
sprintf(buff + ( strchr(sanacfgfile, ':') ? 0 : strlen(buff) ), sanacfgfile, (ULONG)sanaUnit);
if(ConfigFile = Open(buff,MODE_OLDFILE))
{
if(linebuff = AllocMem(LINEBUFFSIZE, MEMF_CLEAR|MEMF_PUBLIC))
{
if(rdargs = AllocDosObject(DOS_RDARGS, NULL))
{
while( FGets( ConfigFile, linebuff, LINEBUFFSIZE - 1) )
{
linenum++;
if(linebuff[0] == '#') /* Skip comment lines */
continue;
rdargs->RDA_Source.CS_Buffer = linebuff;
rdargs->RDA_Source.CS_Length = LINEBUFFSIZE;
rdargs->RDA_Source.CS_CurChr = 0;
/* ReadArgs() requires that the line be null-terminated or funny things happen. */
termchar = (UBYTE *) linebuff + strlen(linebuff);
*termchar = '\n';
termchar++;
*termchar = 0;
for(i = 0; i < NUMARGS ; i++)
arg[i] = NULL;
if( ReadArgs( "SERNAME/A,SERUNIT/A/N,SERBAUD/A/N,IPSTR/A,CD=CARRIERDETECT/S,7WIRE/S,EOFMODE/S,MTU/K/N,THEREST/F", arg, rdargs ) )
{
status = TRUE;
strcpy( sp->serDevName, (UBYTE *)arg[0] );
sp->serUnit = *((ULONG *)arg[1]);
sp->serBaudRate = *((ULONG *)arg[2]);
sp->listen2CD = arg[4] ? TRUE : FALSE;
sp->serHWHS = arg[5] ? TRUE : FALSE;
FreeArgs(rdargs);
break;
}
else
{
msg("Error parsing sana arguments in %s", buff);
break;
}
}
FreeDosObject(DOS_RDARGS, rdargs);
}
FreeMem(linebuff, LINEBUFFSIZE);
}
Close(ConfigFile);
}
return(status);
}
VOID
msg(UBYTE *msg, ...)
{
extern BPTR mystderr;
va_list args;
va_start(args, msg);
if(mystderr)
{
VFPrintf(mystderr, msg, args);
VFPrintf(mystderr, "\n", NULL);
}
else
{
struct Library *IntuitionBase;
static struct EasyStruct es;
if(IntuitionBase = OpenLibrary("intuition.library", 37))
{
es.es_StructSize=sizeof(struct EasyStruct);
es.es_Flags = 0;
es.es_Title = prgname;
es.es_TextFormat = msg;
es.es_GadgetFormat = "OK";
EasyRequestArgs(NULL, &es, 0, args);
CloseLibrary(IntuitionBase);
};
};
va_end(args);
}
BOOL
carrier()
{
/* modem online? */
if (!serialIOReq)
return(FALSE);
serialIOReq->IOSer.io_Command = SDCMD_QUERY;
if ( DoIO((struct IORequest *)serialIOReq) )
msg("Error: Query serial line.");
return( (BOOL)( (serialIOReq->io_Status & ( 1 << 5 ) ) == 0 ) );
}